# CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

project(MyVulkanProject LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# 查找 Vulkan 包 (包含 glslangValidator)
find_package(Vulkan REQUIRED)

# 查找 GLFW
find_package(glfw3 REQUIRED)

# --- 新增：查找 glslangValidator 工具 ---
# Vulkan SDK 通常会提供 glslangValidator
# 它可能在 Vulkan::glslangValidator 目标中，或者我们需要手动查找
# 方法1: 尝试使用 Vulkan 提供的导入目标 (推荐，如果可用)
if(TARGET Vulkan::glslangValidator)
    set(GLSLANG_VALIDATOR_EXECUTABLE $<TARGET_FILE:Vulkan::glslangValidator>)
    message(STATUS "Using Vulkan::glslangValidator")
# 方法2: 如果上述方法不行，尝试在 PATH 中查找
else()
    find_program(GLSLANG_VALIDATOR_EXECUTABLE NAMES glslangValidator glslang-validator
                 PATHS ${VULKAN_SDK}/bin $ENV{VULKAN_SDK}/bin
                 DOC "Path to glslangValidator executable")
    if(NOT GLSLANG_VALIDATOR_EXECUTABLE)
        message(FATAL_ERROR "glslangValidator not found! Please ensure Vulkan SDK is installed and in PATH or VULKAN_SDK is set.")
    endif()
    message(STATUS "Found glslangValidator: ${GLSLANG_VALIDATOR_EXECUTABLE}")
endif()

# --- 新增：定义着色器编译规则 ---
# 创建输出目录 (在构建目录中)
set(SPIRV_OUTPUT_DIR ${CMAKE_BINARY_DIR}/spirv)
file(MAKE_DIRECTORY ${SPIRV_OUTPUT_DIR})

# 定义要编译的着色器
set(GLSL_SHADERS
    ${CMAKE_SOURCE_DIR}/shaders/base.vert
    ${CMAKE_SOURCE_DIR}/shaders/base.frag
)

# 存储生成的 .spv 文件路径
set(SPIRV_FILES)

foreach(GLSL_FILE ${GLSL_SHADERS})
    # 获取文件名 (如 base.vert)
    get_filename_component(FILE_NAME ${GLSL_FILE} NAME)
    # 生成 .spv 文件名 (base.vert.spv)
    set(SPIRV_FILE_NAME "${FILE_NAME}.spv")
    # 生成的 .spv 文件完整路径
    set(SPIRV_FILE_PATH "${SPIRV_OUTPUT_DIR}/${SPIRV_FILE_NAME}")
    # 记录这个生成的文件
    list(APPEND SPIRV_FILES ${SPIRV_FILE_PATH})

    # 为每个着色器文件添加自定义编译命令
    add_custom_command(
        OUTPUT ${SPIRV_FILE_PATH}
        COMMAND ${GLSLANG_VALIDATOR_EXECUTABLE}
            -V ${GLSL_FILE} -o ${SPIRV_FILE_PATH}  # -V 表示编译为 SPIR-V
            --target-env vulkan1.0                # 指定目标环境
        DEPENDS ${GLSL_FILE}                      # 依赖于源文件
        COMMENT "Compiling GLSL shader: ${FILE_NAME} -> ${SPIRV_FILE_NAME}"
        VERBATIM
    )
endforeach()

# --- 新增：创建一个自定义目标来确保所有着色器都被编译 ---
# 这样，当你运行构建时，着色器会自动编译
add_custom_target(CompileShaders ALL
    DEPENDS ${SPIRV_FILES}
    COMMENT "All shaders compiled to SPIR-V"
)

# --- 原有：创建可执行文件 ---
add_executable(MyVulkanApp src/main.cpp)

# 链接库
target_link_libraries(MyVulkanApp PRIVATE Vulkan::Vulkan glfw)

# 将生成的 SPIR-V 文件目录添加到包含路径 (可选)
# 这样你的 C++ 代码可以通过相对路径引用这些 .spv 文件
target_include_directories(MyVulkanApp PRIVATE ${SPIRV_OUTPUT_DIR})

# 确保可执行文件依赖于着色器编译完成
# 这样在链接可执行文件之前，着色器一定会被编译
add_dependencies(MyVulkanApp CompileShaders)

# Windows 特定设置
if(WIN32)
    target_link_libraries(MyVulkanApp PRIVATE vulkan-1)
endif()

# 调试信息
message(STATUS "SPIR-V files will be generated in: ${SPIRV_OUTPUT_DIR}")
